package de.bensoft.jrail.client.ui.locoadmin;

import java.util.List;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListView;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextField;

import javax.inject.Inject;

import jfxtras.labs.scene.control.BeanPathAdapter;

import org.apache.log4j.Logger;

import de.bensoft.jrail.business.entity.Locomotive;
import de.bensoft.jrail.business.service.LocomotiveService;
import de.bensoft.jrail.client.common.JavaFXController;
import de.bensoft.jrail.client.ui.controls.NumberField;
import de.bensoft.jrail.client.ui.mainform.EmbeddedMessagingController;
import de.bensoft.jrail.client.ui.mainform.EmbeddedMessagingController.MessageType;

@JavaFXController(fxml="LocoAdmin.fxml")
public class LocoAdminController {
	
	private static final Logger log = Logger.getLogger(LocoAdminController.class);
	
	//********************************************************************************
	// GENERAL
	//********************************************************************************
	private Locomotive 					currentLoco;
	private ObservableList<Locomotive> 	lstlocos;
	
	//********************************************************************************
	// Services
	//********************************************************************************
	@Inject
	private LocomotiveService 			locService;
	
	@Inject
	private EmbeddedMessagingController  messaging;
	
	//********************************************************************************
	// FXML
	//********************************************************************************
	@FXML
	private ListView<Locomotive> lwLocos;
	
	@FXML
	private ComboBox<Long> cbSpeedsteps;
	
	@FXML
	private TabPane tabPane;
	
	@FXML
	private TextField txtName;
	
	@FXML
	private NumberField nfAddress;
	
	@FXML
	private void onNew() {
		addNewLoco();
	}
	
	@FXML
	private void onRefresh() {
		refreshData();
	}
	
	@FXML
	private void onSave() {
		if(currentLoco != null)
			locService.saveLocomotive(currentLoco);
	}
	
	@FXML
	private void onDelete() {
		if(currentLoco != null) {
			locService.deleteLocomotive(currentLoco);
			refreshData();
		}
	}
	
	
	@FXML
	private void onDriveLoco() {
		openDriveDialog();
	}
	
	@FXML
	private void initialize() {
		init_gui();
	}
	
	//********************************************************************************
	// GUI
	//********************************************************************************
	private void init_gui() {
		refreshData();
	}
	
	private void addNewLoco() {
		Locomotive l = new Locomotive();
		lstlocos.add(l);
	}
	
	BeanPathAdapter<Locomotive> bpa = null;
	
	private void bindFormToDTO(Locomotive loco) {
		
		tabPane.setDisable(true);
		
		if(loco == null) 
			return;
		
		
		
		// Unbind
		if(bpa != null) {
			bpa.unBindBidirectional("name", txtName.textProperty());
			bpa.unBindBidirectional("address", nfAddress.longProperty());
			bpa.unBindBidirectional("speedSteps", cbSpeedsteps.valueProperty());
		}
		
		// Bind
		bpa = new BeanPathAdapter<Locomotive>(loco);
		bpa.bindBidirectional("name", txtName.textProperty());
		bpa.bindBidirectional("address", nfAddress.longProperty());
		bpa.bindBidirectional("speedSteps", cbSpeedsteps.valueProperty(), Long.class);
		
		currentLoco = loco;
		
		tabPane.setDisable(false);	
	}
	
	private void openDriveDialog() {
		//TODO implement drivedialog
		
		/*try {
			
			Result loader = fxmlLoader.load(getClass().getResource("../locodriver/LocoDriver.fxml"));
			Parent p = loader.getRoot();
			LocoDriverController controller = loader.getController();
			
			if(controller != null)
				controller.setActiveLocomotive(currentLoco);
			
			Stage stage = StageBuilder.create().title("Locodriver").scene(new Scene(p)).build();
			stage.setResizable(false);
			stage.sizeToScene();
			stage.show();
			
		} catch (IOException e) {
			e.printStackTrace();
		}*/
		
	}
	
	//********************************************************************************
	// DATA
	//********************************************************************************
	private void refreshData() {	
		tabPane.setDisable(true);
				
		log.info("Refresh locomotive data");
		
		List<Locomotive> lst 	= locService.getAllLocomotives();
		lstlocos 				= FXCollections.observableList(lst);	
		lwLocos.setItems(lstlocos);
		
		log.info("There are " + lstlocos.size() + " Locos!");
		messaging.addMessage(MessageType.INFO, lstlocos.size() + " locomotives fetched!");
		
		// cBoxes
		ObservableList<Long> olst = FXCollections.observableArrayList(Locomotive.AVAILABLE_SPEEDSTEPS);
		cbSpeedsteps.setItems(olst);
		
		lwLocos.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Locomotive>() {

			public void changed(ObservableValue<? extends Locomotive> arg0, Locomotive arg1, Locomotive arg2) {	
				bindFormToDTO(arg2);
			}
				
		});
	}
}
